<?php

/**
 * @version         $Id$
 * @create          2012-4-8 8:48:15 By xjiujiu
 * @description     HongJuZi Framework
 * @copyRight       Copyright (c) 2011-2012 http://www.xjiujiu.com.All right reserved
 * HongJuZi Framework
 */
defined('_HEXEC') or die('Restricted access!');

//导入引用文件
HClass::import('app.oauth.action.oauthaction, config.popo.userpopo, model.usermodel');

/**
 * 管理主页的动作类 
 * 
 * 主要处理后台管理主页的相关请求动作 
 * 
 * @author          xjiujiu <xjiujiu@foxmail.com>
 * @package         app.admin.action
 * @since           1.0.0
 */
class AuserAction extends OAuthAction
{

    /**
     * @var private $_linkedData 关联对象
     */
    private $_linkedData;

    /**
     * 构造函数 
     * 
     * 初始化类里的变量 
     * 
     * @access public
     */
    public function __construct() 
    {
        $this->_popo    = new UserPopo();
        $this->_model   = new UserModel($this->_popo);
        $this->_linkedData  = HClass::quickLoadModel('linkeddata');
    }
	
    /**
     * 微信登陆
     * 通过微信号里生成的苏测校驗KEY的方式,不是正常的微信登陆
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function wx()
    {
        HVerify::isEmpty(HRequest::getParameter('token'), '校验码');
        $key    = HRequest::getParameter('token');
        $linkedData     = HClass::quickLoadModel('linkeddata');
        $linkedData->setRelItemModel('user', 'login');
        $login  = $linkedData->getRecordByWhere(
            '`extend` = \'' . $key . '\''
            . ' AND `rel_id` > \'' . $_SERVER['REQUEST_TIME'] . '\''
        );
        if(!$login) {
            return HResponse::warn('您的登陆信息已经过期，请重新登陆2！', HResponse::url());
        }
        $linkedData->deleteByWhere(
            '`item_id` = \'' . $login['item_id'] . '\''
            . ' AND `rel_id` < \'' . $_SERVER['REQUEST_TIME'] . '\''
        );
        $linkedData->setRelItemModel('user', 'openid');
        $openId     = $linkedData->getRecordByWhere('`item_id` = \'' . $login['item_id'] . '\'');
        if(!$openId) {
            return HResponse::warn('您还没有关注我们的公众号，还不能登陆哦～', HResponse::url());
        }
        if(1 == $openId['extend']) {
            $this->_syncUserInfoByWx($openId['item_id'], $openId['rel_id']);
            $linkedData->editByWhere(array('extend' => 2), '`id` = ' . $openId['id']);
        }
        $record     = $this->_model->getRecordById($openId['rel_id']);
        $this->_setUserLoginInfo($record);
        $this->_setUserRights($record['parent_id']);
        $to         = HRequest::getParameter('to');
        $to         = 'scenter' !== $to ? 'ucenter' : 'scenter';
        HSession::setAttribute('to_center', $to, 'root');

        HResponse::redirect(HResponse::url($to, '', 'mobile'));
    }

    /**
     * 同步微信用户信息
     * @param $openId
     * @return array
     */
    private function _syncUserInfoByWx($openId, $userId)
    {
        HClass::import('vendor.sdk.weixin.WechatUserHelper');
        HClass::import('hongjuzi.filesystem.hdir');
        $wxCfg          = HObject::GC('WECHAT');
        $wechatUser     = new WechatUserHelper($wxCfg['appid'], $wxCfg['secret']);
        $wechatUser->requestAccessToken();
        $data           = array();
        $json           = $wechatUser->getInfo($openId);
        $data['true_name']  = $json['nickname'];
        $data['image_path'] = $json['headimgurl']; //$this->_downloadAvatar($json['headimgurl']);
        $data['sex']        = in_array($json['sex'], array(1, 2)) ? $json['sex'] : 3;
        $this->_model->editByWhere($data, '`id` = ' . $userId);
    }

    /**
     * 小程序登陆
     */
    public function loginbyoauth2()
    {
        try{            
            $code       = HRequest::getParameter('code');
            if(!$code){
                throw new HApiException('登陆凭证code不能为空');
            }
            HClass::import('vendor.sdk.xiaochengxu.xiaochengxu');
            $xcxCfg     = HObject::GC('XIAOCHENGXU');
            $xcx        = new Xiaochengxu($xcxCfg['appid'], $xcxCfg['secret']);
            $result     = $xcx->sessionKey($code);
            $openId     = $result['openid'];
            $accessToken= md5($openId . $result['session_key'] . $_SERVER['REQUEST_TIME'] . 'hjz-xiaochengxu!!!');
            $linkedData = HClass::quickLoadModel('linkeddata');
            $linkedData->setRelItemModel('user', 'openid');
            $info       = $linkedData->getRecordByWhere('`item_id` = \'' . $openId . '\'');
            if(!$info){
                $userId = $this->_addUserToWebSite();
                $temp   = array(
                    'item_id' => $openId,
                    'rel_id' => $userId,
                    'extend' => 2
                );
                $linkedData->add($temp);
                $info = $temp;
            }
            $platform   = 4;
            $linkedData->setRelItemModel('user', 'accesstoken');
            $tokenInfo  = $linkedData->getRecordByWhere('`item_id` = \'' . $accessToken . '\' AND `type` = ' . $platform);
            if(!$tokenInfo){
                $extend = array(
                    'openid' => $openId,
                    'session_key' => $result['session_key'],
                    'expire' => $_SERVER['REQUEST_TIME'] + 86400,
                    'access_token' => $accessToken
                );
                $temp   = array(
                    'item_id' => $accessToken,
                    'rel_id' => $info['rel_id'],
                    'type' => $platform,
                    'extend' => serialize($extend)
                );
                $list       = $linkedData->getSomeRowsByAll(1, '*',  '`rel_id` = ' . $info['rel_id'], '`id` DESC');
                $record     = array();
                $ext        = array();
                if($list){
                    $record = $list[0];
                    $ext    = unserialize($record['extend']);
                }
                if($ext && $ext['expire'] > $_SERVER['REQUEST_TIME']){
                    $ext['expire'] = $_SERVER['REQUEST_TIME'] + 86400;
                    $linkedData->editByWhere(array('extend' => serialize($ext)), '`id` = ' . $record['id']);
                    $tokenInfo = $ext;
                    $accessToken = $ext['access_token'];
                }else{
                    $linkedData->add($temp);
                    $tokenInfo = $temp;
                }
            }else{
                $extend = unserialize($tokenInfo['extend']);
                $extend['expire'] = $_SERVER['REQUEST_TIME'] + 86400;
                $linkedData->editByWhere(array('extend' => serialize($extend)), '`id` = ' . $tokenInfo['id']);
                $accessToken = $extend['access_token'];
            }
            $returnData = array(
                'access_token' => $accessToken
            );

            HResponse::json(array('rs' => true, 'data' => $returnData));
        }catch(Exception $ex){
            throw new HApiException($ex->getMessage());
        }
    }

    /**
     * 小程序登陆 通过输入账号
     */
    public function loginbyaccount()
    {
        try{
            $name       = HRequest::getParameter('name');
            $password   = HRequest::getParameter('password');
            if(!$name){
                throw new HApiException('用户名不能为空');
            }
            if(!$password){
                throw new HApiException('密码不能为空');
            }
            $where      = '`name` = \'' . $name . '\' OR `phone` = \'' . $name . '\'';
            $userInfo   = $this->_model->getRecordByWhere($where);
            if(empty($userInfo)) {
                throw new HApiException('用户名不正确，请确认！');
            }
            $password   = $this->_encodePassword($password, $userInfo['salt']);
            if($userInfo['password'] != $password) {
                throw new HApiException('密码不正确，请确认！');
            }
            $accessToken= md5($userInfo['id'] . $_SERVER['REQUEST_TIME'] . 'hjz-xiaochengxu!!!');
            $linkedData = HClass::quickLoadModel('linkeddata');            
            $linkedData->setRelItemModel('user', 'accesstoken');
            $platform   = 4;
            $tokenInfo  = $linkedData->getRecordByWhere('`item_id` = \'' . $accessToken . '\' AND `type` = ' . $platform);
            if(!$tokenInfo){
                $extend = array(
                    'openid' => $userInfo['id'],
                    'session_key' => $userInfo['id'],
                    'expire' => $_SERVER['REQUEST_TIME'] + 86400,
                    'access_token' => $accessToken
                );
                $temp   = array(
                    'item_id' => $accessToken,
                    'rel_id' => $userInfo['id'],
                    'extend' => serialize($extend),
                    'type' => $platform
                );
                $list       = $linkedData->getSomeRowsByAll(1, '*',  '`rel_id` = ' . $userInfo['id'], '`id` DESC');
                $record     = array();
                $ext        = array();
                if($list){
                    $record = $list[0];
                    $ext    = unserialize($record['extend']);
                }
                if($ext && $ext['expire'] > $_SERVER['REQUEST_TIME']){
                    $ext['expire'] = $_SERVER['REQUEST_TIME'] + 86400;
                    $linkedData->editByWhere(array('extend' => serialize($ext)), '`id` = ' . $record['id']);
                    $tokenInfo = $ext;
                    $accessToken = $ext['access_token'];
                }else{
                    $linkedData->add($temp);
                    $tokenInfo = $temp;
                }
            }else{
                $extend = unserialize($tokenInfo['extend']);
                $extend['expire'] = $_SERVER['REQUEST_TIME'] + 86400;
                $linkedData->editByWhere(array('extend' => serialize($extend)), '`id` = ' . $tokenInfo['id']);
                $accessToken = $extend['access_token'];
            }
            $returnData = array(
                'access_token' => $accessToken
            );

            HResponse::json(array('rs' => true, 'data' => $returnData));
        }catch(Exception $ex){
            throw new HApiException($ex->getMessage());
        }
    }

    /**
     * 添加用户的基础信息到网站
     */
    protected function _addUserToWebSite()
    {
        $user           = HClass::quickLoadModel('user');
        $actor          = HClass::quickLoadModel('actor');
        $actorInfo      = $actor->getRecordByIdentifier('member');
        $salt           = HString::createRandStr(5);
        $nickName       = '';
        $total          = $user->getTotalRecords();
        $data           = array(
            'name' => $nickName ? $nickName : str_repeat('0', 6 - mb_strlen($total)) . $total,
            'parent_id' => $actorInfo['id'],
            'salt' => $salt,
            'u_from' => 'xiaochengxu',
            'login_time' => $_SERVER['REQUEST_TIME'],
            'ip' => HRequest::getClientIp()
        );
        $id             = $user->add($data);
        if(1 > $id){
            throw new HApiException('用户数据写入失败～，请稍后再试！');
        }

        return $id;
    }

    /**
     * 用户登陆请求动作 
     * 
     * 验证用户的登陆信息
     * 
     * @access public
     */
    public function login()
    {
        $this->_loginByEmail();

        HResponse::redirect($this->_getNextUrl());
    }

    /**
     * 用户名登陆
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function nlogin()
    {
        $this->_loginByName();

        HResponse::redirect($this->_getNextUrl());
    }

    /**
     * 得到下一跳地址
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @return String 得到下一跳地址
     */
    private function _getNextUrl()
    {
        return HRequest::getParameter('next_url') ? HRequest::getParameter('next_url') : HResponse::url();
    }

    /**
     * 管理员异步登录
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function aadminlogin()
    {
        HVerify::isAjax();
        $this->_checkVCodeMust();
        $name     = HVerify::isEmptyByVal(HRequest::getParameter('name'));
        $this->_verifyUserLoginInfo(
            '(`email` = \'' . $name . '\''
            . ' OR `name` = \'' . $name . '\''
            . ' OR `phone` = \'' . $name . '\')'
        );

        HResponse::json(array('rs' => true));
    }

    /**
     * 前台异步登录
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function asellerlogin()
    {
        HVerify::isAjax();
        $this->_checkVCodeMust();
        $name     = HVerify::isPhone(HRequest::getParameter('name'));
        $where    = '(`name` = \'' . $name . '\' OR `phone` = \'' . $name . '\')'; 
        $this->_verifyUserLoginInfo($where);

        HResponse::json(array('rs' => true));
    }

    /**
     * 前台异步登录
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function aloginbyphone()
    {
        HVerify::isAjax();
        $name     = HVerify::isPhone(HRequest::getParameter('name'));
        $this->_verifyUserLoginInfo(' `phone` = \'' . $name . '\'');

        HResponse::json(array('rs' => true));
    }

    /**
     * 异步登录
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function alogin()
    {
        HVerify::isAjax();
        $name     = HVerify::isStrLen(HRequest::getParameter('name'), '账号', 2, 50);
        $this->_verifyUserLoginInfo(
            '(`email` = \'' . $name . '\'' 
            . ' OR `name` = \'' . $name . '\''
            . ' OR `phone` = \'' . $name . '\')'
        );

        HResponse::json(array('rs' => true));
    }

    /**
     * 名称异步登录
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function anlogin()
    {
        $this->_loginByName();

        HResponse::json(array('rs' => true));
    }
    
    /**
     * 通过邮箱登陆
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     */
    private function _loginByEmail()
    {
        $email      = HRequest::getParameter('email');
        $email      = !$email ? HRequest::getParameter('name') : $email;
        HVerify::isEmail($email);
        $this->_verifyUserLoginInfo('`email` = \'' . $email . '\'');
    }

    /**
     * 验证用户登陆信息
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @param  $where 验证条件
     */
    private function _verifyUserLoginInfo($where)
    {
        $password = HVerify::isStrLen(HRequest::getParameter('password'), '登录密码', 6, 20);
        /*$vcode  = strtolower(HSession::getAttribute('vcode'));
        if($vcode && $vcode != strtolower(HRequest::getParameter('vcode'))) {
            throw new HVerifyException('验证码不正确！');
        }*/
        $userInfo   = $this->_model->getRecordByWhere($where);
        if(empty($userInfo)) {
            throw new HVerifyException(HTranslate::__('用户名不正确，请确认！'));
        }
        $password   = $this->_encodePassword($password, $userInfo['salt']);
        if($userInfo['password'] != $password) {
            throw new HVerifyException(HTranslate::__('密码不正确，请确认！'));
        }
        $this->_setUserLoginInfo($userInfo);
        $this->_setUserRights($userInfo['parent_id']);
        $this->_setReuserMe($userInfo);
        $this->_recordUserLoginLog();
    }

    /**
     * 切换到对应的用户角色
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function loginas() 
    {
        if('root' !== HSession::getAttribute('actor', 'user')) {
            throw new HVerifyException('您没有此操作权限哦！');
        }
        $id     = HVerify::isEmptyByVal(HRequest::getParameter('id'), '编号');
        $userInfo = $this->_model->getRecordById($id);
        if(!$userInfo) {
            throw new HVerifyException('用户不存在，请确认！');
        }
        if(1 == $userInfo['parent_id']) {
            throw new HVerifyException('您不能切换到管理员哦！');
        }
        HSession::setAttribute('backup_logined_id', HSession::getAttribute('id', 'user'));
        $this->_setUserLoginInfo($userInfo);
        $this->_setUserRights($userInfo['parent_id']);
        HResponse::succeed('切换成功，正在为您导航到首页！', HResponse::url());
    }

    /**
     * 切换到回自己的角色
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function loginback() 
    {
        if(!HSession::getAttribute('backup_logined_id', 'root')) {
            throw new HVerifyException('您没有此操作权限哦！');
        }
        $userInfo = $this->_model->getRecordById(HSession::getAttribute('backup_logined_id', 'root'));
        if(!$userInfo) {
            throw new HVerifyException('用户不存在，请确认！');
        }
        if(1 != $userInfo['parent_id']) {
            throw new HVerifyException('您不是管理员，不能切换哦！');
        }
        HSession::destroy('backup_logined_id', 'root');
        $this->_setUserLoginInfo($userInfo);
        $this->_setUserRights($userInfo['parent_id']);
        HResponse::succeed('切换成功，正在为您导航到管理员界面！', HResponse::url('index', '', 'admin'));
    }
    
    /**
     * 登录方法内部使用 
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     */
    private function _loginByName()
    {
        $name     = trim(HRequest::getParameter('name'));
        HVerify::isStrLen($name, HTranslate::__('用户名'), 2, 50);
        $this->_verifyUserLoginInfo(
            '(`name` = \'' . $name . '\' OR `email` = \'' . $name . '\''
            . ' OR `phone` = \'' . $name . '\')'
        );
    }

    /**
     * 设置记住我的登录状态
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @param  UserModel 用户对象
     * @param  $userInfo 当前的用户信息集
     */
    private function _setReuserMe($userInfo)
    {
        if(HRequest::getParameter('remember')) { 
            $hash               = HString::getUUID() . ip2long(HRequest::getClientIp());
            $this->_model->editByWhere(array('hash' => $hash), '`id` = ' . $userInfo['id']);
            // 7 天自动登陆
            HSession::setAttribute('hjz_keep_login', $hash);
            setcookie('hjz_keep_login', $hash, time() + 3600 * 24 * 7);
        }
    }

    /**
     * 检测用户是否已经登陆 
     * 
     * @access public static
     * @throws HVerifyException 验证异常
     */
    public static function isLogined()
    {
        if(false === self::isLoginedByBool()) {
            throw new HVerifyException('您的登陆信息已经过期，请重新登陆！');      
        }
    }

    /**
     * 通过布尔查看是否已经登陆
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     * @return bool
     */
    public static function isLoginedByBool()
    {
        if(!HSession::getAttribute('id', 'user') 
            || $_SERVER['REQUEST_TIME'] > HSession::getAttribute('time', 'user')) {
            if(HSession::getAttribute('hjz_keep_login') && !$_COOKIE['hjz_keep_login']) {
                setcookie('hjz_keep_login', HSession::getAttribute('hjz_keep_login'), time() + 3600 * 24);
            }
            if(HSession::getAttribute('is_logout', 'user') || !$_COOKIE['hjz_keep_login']) {
                return false;
            }
            $auser  = new AuserAction();
            return $auser->loginByKeepLoginStatus();
        }

        return true;
    }

    /**
     * 通过登陆状态登陆
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access protected
     */
    public function loginByKeepLoginStatus()
    {
        if(!$_COOKIE['hjz_keep_login']) { return false; }
        $ip     = long2ip(substr($_COOKIE['hjz_keep_login'], 32));
        if(HRequest::getClientIp() != $ip) {
            return false;
        }
        $userInfo = $this->_model->getRecordByWhere('`hash` =\'' . $_COOKIE['hjz_keep_login'] . '\'' );
        if($userInfo) {
            $this->_setUserLoginInfo($userInfo);
            $this->_setUserRights($userInfo['parent_id']);
            return true;
        }
        $_COOKIE['hjz_keep_login']  = '';

        return false;
    }

    /**
     * 找回密码及发送邮件提醒
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function afindpwd()
    {
        HVerify::isAjax();
        $vcode  = strtolower(HRequest::getParameter('vcode'));
        if($vcode != HSession::getAttribute('vcode')) {
            throw new HRequestException('验证码不正确！');
        }
        HVerify::isEmail(HRequest::getParameter('email'));
        $userInfo     = $this->_model->getRecordByWhere(
            '`email` = \'' . HRequest::getParameter('email') . '\''
        );
        if(!$userInfo) {
            throw new HVerifyException('该邮箱还没未注册，请确认～');
        }
        $hash       = $this->_model->getFindPwdHashByWhere(
            '`item_id` = ' . $userInfo['id'] 
            . ' AND `extend` > \'' . $_SERVER['REQUEST_TIME'] . '\''
        );
        if($hash) {
            throw new HVerifyException('找回密码连接已经发送，请到此邮箱查收～');
        }
        $hash   = HString::getUUID();
        if(false === $this->_sendFindPwdEmailHasPwd($userInfo, $hash)) {
            throw new HRequestException('服务器繁忙，邮件发送失败！请您稍后再试～');
        }
        $this->_addUserHash($hash, $userInfo);

        HResponse::json(array('rs' => true));
    }

    /**
     * 添加找回密码校验码
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     * @param  string $hash 安全码
     * @param  string $userInfo 用户信息
     */
    private function _addUserHash($hash, $userInfo)
    {
        $data   = array(
            'rel_id' => $hash,
            'item_id' => $userInfo['id'],
            'extend' => (intval($_SERVER['REQUEST_TIME']) + 3600 * 24),
            'author' => $userInfo['id']
        );
        $userHashModel  = HClass::quickLoadModel('linkeddata');
        $userHashModel->setRelItemModel('user', 'hash');
        if(!$userHashModel->add($data)) {
            throw new HRequestException('服务器繁忙，请您稍后再试～');
        }   
    }

    /**
     * 重置密码 从邮件过来的
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function doresetpwd()
    {
        HVerify::isAjax();
        HVerify::isEmpty(HRequest::getParameter('hash'), '验证口令');
        $password   = HRequest::getParameter('password', false);
        HVerify::isStrLen($password, '新密码', 6, 20);
        if($password != HRequest::getParameter('repassword', false)) {
            throw new HVerifyException('两次密码不一致！'); 
        }
        $hashInfo    = $this->_model->getFindPwdHashByWhere(
            '`rel_id` = \'' . HRequest::getParameter('hash') . '\''
        );
        if(!$hashInfo) {
            throw new HVerifyException('请求无效，请重发找回密码邮件～');
        }
        if($hashInfo['extend'] < intval($_SERVER['REQUEST_TIME'])) {
            $this->_model->deleteFindPwdHash($hashInfo['rel_id']);
            throw new HVerifyException('请求已经过期，请重发找回密码邮件～');
        }
        $record     = $this->_model->getRecordById($hashInfo['id']);
        $data       = array(
            'id' => $hashInfo['item_id'],
            'password' => md5($password . $record['salt'])
        );
        if(1 > $this->_model->edit($data)) {
            throw new HRequestException('服务器繁忙，请您稍后再试，修改密码失败～');
        }
        $this->_model->deleteFindPwdHash($hashInfo['rel_id']);
        HResponse::json(array('rs' => true));
    }
    
    /**
     * 添加用户 
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function register()
    {
        $this->_register();

        HResponse::succeed('恭喜您，注册成功！正在为您导航到下一个页面～', $this->_getNextUrl());
    }

    /**
     * 异步注册
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function aregister()
    {
        HVerify::isAjax();
        $this->_register();

        HResponse::json(array('rs' => true, 'actor' => HRequest::getParameter('actor')));
    }
    
    /**
     * 注册使用内部使用
     *
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     */
    private function _register()
    {
        $name       = HVerify::isEmptyByVal(HRequest::getParameter('name'), '用户名');
        $phone      = HVerify::isMobile(HRequest::getParameter('phone'));
        $password   = HVerify::isStrLen(HRequest::getParameter('password'), '密码', 6, 20);
        //$this->_checkVCode();
        HVerify::isEmpty(HRequest::getParameter('agree'), '服务协议');
        //校验码
        $code       = HVerify::isEmptyByVal(HRequest::getParameter('code'), '校验码');
        $this->_checkCodeIsOk($code, $phone);
        $where      = '`phone` = \'' . $phone . '\'';
        $record     = $this->_model->getRecordByWhere($where);
        if($record) {
            throw new HVerifyException('手机号已经被注册，请您另换一个！');
        }
        if($record['name'] == $name) {
            throw new HVerifyException('用户名已经被注册，请您另换一个！');
        }
        $actor          = 'member';
        $actorInfo      = $this->_getActorByIdentifier($actor);
        if(!$actorInfo) {
            throw new HVerifyException('没有这个类别哦，请确认！');
        }
        $salt           = HString::createRandStr(5);
        $data           = array(
            'name' => $name,
            'phone' => $phone,
            'true_name' => $name,
            'salt' => $salt,
            'password' => $this->_encodePassword($password, $salt),
            'parent_id' => $actorInfo['id'],
            'login_time' => $_SERVER['REQUEST_TIME'],
            'ip' => HRequest::getClientIp(),
            'author' => 0
        );
        $userId     = $this->_model->add($data);
        if(!$userId) {
            throw new HVerifyException('非常抱歉，服务器正忙，请你稍后再试！');
        }
        $this->_addNewHomersInfo($userId);
        $data['id']     = $userId;
        $this->_updatePhoneCodeStatus($code, $phone);
        $this->_setUserLoginInfo($data);
        $this->_setUserRights($actorInfo);
    }

    /**
     * 更新验证码正常
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @param $code 验证码
     * @param  $phone 手机号
     */
    private function _updatePhoneCodeStatus($code, $phone)
    {
        $where          = '`item_id` = \'' . $code . '\' AND `extend` = 1'
            . ' AND `rel_id` = ' . $phone;
        $this->_linkedData->editByWhere(array('extend' => 2), $where);
    }

    /**
     * 添加用户扩展信息
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @param $userId 用户id
     */
    private function _addNewHomersInfo($userId)
    {
        $data       = array(
            'parent_id' => $userId,
            'author' => $userId,
        );
        $userExtend     = HClass::quickLoadModel('userextend');
        $userExtend->add($data);
    }

    /**
     * 发送用户邮箱，验证激活用户
     * 
     * @param string $email:接收人邮件地址
     * @param string $name:邮件接收人姓名
     * @param string $hash:接收人hash值
     * @param string $password:邮件接收人原始登录密码
     * 
     * @return boolean 发送成功true，反之false
     * 
     * @author licheng
     * @access private
     */
    private function _sendUserValidate($email,$name,$hash,$password)
    {
        HClass::import('hongjuzi.net.hemail');
        $model      = new HEmail(HObject::GC('MAIL'));
        $activeUrl  = HResponse::url('enter/setaccount', 'hash=' . $hash.'&password='.$password, 'cms');
        $title      = '【派兵点匠】用户账号激活';
        ob_start();
        require(HResponse::path('public') . 'email-active-user.tpl');
        $body       = ob_get_contents();
        ob_end_clean();
        return $model->send('【派兵点匠】用户账号激活', $email, null, $body);
    }
    
     /**
      * 发送带有密码的邮箱
      *
      * @param  [type] $userInfo [description]
      * @return [type]           [description]
      */
     private function _sendFindPwdEmailHasPwd($userInfo, $hash)
     {
        HClass::import('hongjuzi.net.hemail');
        $model  = new HEmail(HObject::GC('MAIL'));
        $pwdUrl = HResponse::url('enter/resetpwd', 'hash=' . $hash, 'cms');
        $url    = HResponse::url();
        ob_start();
        require(HResponse::path('public') . 'email-find-pwd.tpl');
        $body       = ob_get_contents();
        ob_end_clean();

        return $model->send('Hi, ' . $userInfo['name'] .'重置登录密码', $userInfo['email'], null, $body);  
     }

    /**
     * 用户注销动作 
     * 
     * 注销用户当前的登陆记录信息，回到初始的状态 
     * 
     * @access public
     */
    public function logout()
    {
        HSession::destroy(null, 'user');
        HSession::destroy(null, 'root');
        $this->_model->editByWhere(
            array('hash' => md5(time())), 
            '`hash` =\'' . $_COOKIE['hjz_keep_login'] . '\'' 
        );
        setcookie('hjz_keep_login', '', time() - 100000);

        HResponse::redirect(Hresponse::url());
    }

    /**
     * 记录用户登陆信息
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     */
    private function _recordUserLoginLog()
    {
        $data   = array(
            'login_time' => $_SERVER['REQUEST_TIME'],
            'ip' => HRequest::getClientIp()
        );
        $this->_model->editByWhere($data, '`id` = ' . HSession::getAttribute('id', 'user'));
    }

    /**
     * 绑定现有用户
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function bind()
    {
        if('unknow' != HSession::getAttribute('actor', 'user')) {
            throw new HRequestException('您没有此操作权限！');
        }
        $name       = HVerify::isPhone(HRequest::getParameter('name'), '手机号码');
        $password   = HVerify::isEmptyByVal(HRequest::getParameter('password'), '密码');
        $where  = '(`name` = \'' . $name . '\' OR `phone` = \'' . $name . '\')';
        $record     = $this->_model->getRecordByWhere($where);
        if(!$record)  {
            throw new HVerifyException('您的手机号码错误，请仔细核对哇！');
        }
        $password   = $this->_encodePassword($password, $record['salt']);
        if($record['password'] != $password)  {
            throw new HVerifyException('您的密码错误，请仔细核对哇！');
        }
        $srcUser     = $this->_model->getRecordById(HSession::getAttribute('id', 'user'));
        //删除原数据
        $this->_deleteSrcUserData();
        //掉换绑定信息
        $this->_switchUserLinkeddata($record, $srcUser);
        //自动登录
        $this->_setUserLoginInfo($record);
        $this->_setUserRights($record['parent_id']);

        HResponse::succeed('恭喜您，绑定成功正在为您导航到首页，祝您使用愉快！', HResponse::url());
    }

    /**
     * 删除原有数据
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     */
    private function _deleteSrcUserData()
    {
        $where  = '`id` = ' . HSession::getAttribute('id', 'user');
        $this->_model->deleteByWhere($where);
    }

    /**
     * 切换到最新的用户数据
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @param $newUserInfo 新用户数据
     * @param  $srcUser 原用户数据
     */
    private function _switchUserLinkeddata($newUserInfo, $srcUser)
    {
        if('weixin' == $srcUser['u_from']) {
            $linkedData     = HClass::quickLoadModel('linkeddata');
            $linkedData->setRelItemModel('user', 'openid');
            $data           = array('rel_id' => $newUserInfo['id']);
            $linkedData->editByWhere($data, '`rel_id` = ' . $srcUser['id']);
            return;
        }
        if('qq' == $srcUser['u_from']) {
            $shareCfg       = HClass::quickLoadModel('shareCfg');
            $where          = '`parent_id` = \'' . $srcUser['id'] . '\' AND `identifier` = \'qq\'';
            $data           = array(
                'parent_id' => $newUserInfo['id']
            );
            $shareCfg->editByWhere($data, $where);
            return;
        }
    }

    /**
     * 更新手机绑定
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access public
     */
    public function updatephone()
    {
        $phone  = HVerify::isPhone(HRequest::getParameter('phone'));
        $code   = HVerify::isEmptyByVal(HRequest::getParameter('code'), '手机验证码');
        $this->_checkVCode();
        $this->_checkPhoneUsed($phone);
        $this->_checkCodeIsOk($code, $phone);
        $data   = array(
            'phone' => $phone
        );
        $this->_model->editByWhere($data, '`id` = ' . HSession::getAttribute('id', 'user'));
        $this->_updatePhoneCodeStatus($code, $phone);
        HSession::setAttribute('phone', $phone, 'user');
        HResponse::json(array('rs' => true));
    }

    /**
     * 检测手机号是否被使用过
     * 
     * @author xjiujiu <xjiujiu@foxmail.com>
     * @access private
     * @param $phone 手机号
     * @throws HVerifyException 异常
     */
    private function _checkPhoneUsed($phone)
    {
        $user   = HClass::quickLoadModel('user');
        if($user->getRecordByWhere('`phone` = \'' . $phone . '\'')) {
            throw new HVerifyException('手机号码已经被他人使用，请换一个！');
        }
    }

}

?>
